package filters;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import admin.system.user.UserBean;

import com.util.LogUtil;

/**
 * All pre-request and post-request processing should be handled in this 
 * global filter.
 * 
 * @author KENNETHLCH
 */
public class GlobalRequestInterceptor implements Filter {

    @Override
	public void destroy() {
        // TODO Auto-generated method stub

    }

    /**
     * Stores current thread ID in the MDC so that we can have it logged.
     * The thread ID is useful to group log messages together when analyzing
     * a large file of interleaved log messages.
     * 
     * The %t placeholder in PatternLayout doesn't work in environments that
     * the thread name is insufficient to uniquely identify a running thread.
     */
    private void setThreadID() {
        LogUtil.setThreadID();
    }

    /**
     * Stores the session ID of the current request in the MDC so that we can 
     * have it logged. The session ID is useful to group together log messages 
     * of a particular session.
     * 
     * Note that this method keeps the hashed value of the session ID instead
     * of the actual value, since the the actual ID varies across platforms
     * and maybe very long. The hash should be sufficient to uniquely identify
     * a session within the time frame of an investigation.
     *  
     * @param req 
     */
    private void setSessionID(ServletRequest req) {
        HttpSession session = ((HttpServletRequest) req).getSession(false);
        
        if (session != null) {
            LogUtil.setSessionID(Integer.toHexString(session.getId().hashCode()));
        } else {
            LogUtil.setSessionID("");
        }
    }
    
    /**
     * Stores the user ID of the current request in the MDC so that we can 
     * have it logged. The user ID is useful to group together log messages 
     * of a particular user.
     * 
     * @param req
     * @see admin.LoginServlet
     */
    private void setUserID(ServletRequest req) {
        HttpSession session = ((HttpServletRequest) req).getSession(false);
        UserBean user = session != null ? (UserBean) session.getAttribute("user") : null;
        
        if (user != null) {
            LogUtil.setUserID(user.getUser_id());
        } else {
            LogUtil.setUserID("");
        }
    }
    
    @Override
	public void doFilter(ServletRequest req, ServletResponse rsp,
            FilterChain chain) throws IOException, ServletException {

        // Pre-request processing
        setThreadID();
        setSessionID(req);
        setUserID(req);
        
        // To avoid proxy caching
        HttpServletResponse httprsp = (HttpServletResponse) rsp;
        // Pragma: no-cache directive causes problem with SSL file download in IE...
        //httprsp.setHeader("Pragma", "no-cache");
        httprsp.setHeader("Cache-Control", "private");
        httprsp.setDateHeader("Expires", 0);
        
        try {
            chain.doFilter(req, rsp);
        } finally {
            // Post-request processing
            LogUtil.clearDC();
        }
    }

    @Override
	public void init(FilterConfig arg0) throws ServletException {

    }

}
